package com.example.chat03.config;


import com.example.chat03.model.StompAuthenticatedUser;
import com.example.chat03.service.ChatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;

import javax.annotation.Resource;

@Component
public class WebSocketEventListener {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketEventListener.class);

    @Autowired
    private AmqpAdmin amqpAdmin;
    @Autowired
    private TopicExchange exchange;
    @Resource(name = "messageContainer")
    private SimpleMessageListenerContainer container;
    @Autowired
    ChatService chatService;

    @EventListener
    public void handleWebSocketConnectListener(SessionConnectedEvent event) {
        logger.info("Received a new web socket connection");
        StompAuthenticatedUser user = (StompAuthenticatedUser) event.getUser();
        if (user != null) {
            // 创建一个 以用户名为 名的队列，并通过 用户名 为 routingkey 将 该队列绑定到 exchange 交换机上
            Queue queue = new Queue(RabbitConfig.MSG_TOPIC_QUEUE + "." + user.getName());
            amqpAdmin.declareQueue(queue);
            amqpAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(user.getName()));

            if (container != null && container.isRunning()) {
                container.stop();
            }

            container.addQueues(queue);
            container.setMaxConcurrentConsumers(1);
            container.setConcurrentConsumers(1);
            //设置确认模式手工确认
            container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
            container.setMessageListener(new ChannelAwareMessageListener() {
                public void onMessage(Message message, com.rabbitmq.client.Channel channel) throws Exception {
                    byte[] body = message.getBody();
                    String msg = new String(body);
                    logger.info("rabbitmq收到消息 : " + msg);
                    boolean sendToWebsocket = chatService.sendMsg(msg);

                    if (sendToWebsocket) {
                        logger.info("消息处理成功！ 已经推送到websocket！");
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费
                    }
                }

            });
            container.start();
        }
    }

    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        //连接销毁，将监听的 队列删除
        if (container != null && container.isRunning()) {
            container.stop();
        }
        container.removeQueueNames(RabbitConfig.MSG_TOPIC_QUEUE + "." + event.getUser().getName());
        container.start();

    }
}
